using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Collections;
using System.Windows.Forms;
using Dracham.GUI.Controls;

namespace Dracham.Network
{
    public delegate void HandlerMethod(DateTime serverTime);

    public class NetworkHandler
    {
        private TcpClient client;
        private Byte[] receiveBytes = new Byte[2];
        private List<HandlerInvoker> handlers;

        internal NetworkHandler(TcpClient client)
        {
            this.client = client;
            this.handlers = new List<HandlerInvoker>();

            BeginReceive();
        }

        public void AddHandler(RequestType rt, HandlerMethod method)
        {
            this.handlers.Add(new HandlerInvoker(rt, method));
        }

        private void BeginReceive()
        {
            if (client.Connected)
            {
                this.client.Client.BeginReceive(receiveBytes, 0, receiveBytes.Length, SocketFlags.None, new AsyncCallback(ReceiveData), null);
            }
            else
            {
                Dracham.UserInterface.txtMessages.Text.Add(new TextViewer.TextString("Server disconnected!!", Microsoft.Xna.Framework.Graphics.Color.Gray));
            }
        }

        private void ReceiveData(IAsyncResult result)
        {
            if (client.Connected)
            {
                SocketError serror;
                Int32 bytesRecv = this.client.Client.EndReceive(result, out serror);

                if (bytesRecv > 0)
                {
                    Object _rt = Enum.Parse(typeof(RequestType), Encoding.UTF8.GetString(receiveBytes));

                    if (_rt == null)
                    {
                        BeginReceive();
                        return;
                    }

                    RequestType rt = (RequestType)_rt;
                    String ticks = Dracham.DrachamNetwork.ReceiveString(Int64.MaxValue.ToString().Length);
                    DateTime st = new DateTime(Int64.Parse(ticks));

                    HandleRequestType(rt, st);
                }

                BeginReceive();
            }
        }



        private void HandleRequestType(RequestType rt, DateTime serverTime)
        {
            this.handlers.ForEach(delegate(HandlerInvoker hi)
            {
                if (hi.RequestType == rt)
                    hi.Method(serverTime);
            });
        }
    }
}
